﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace TransparentAccords
{
    public partial class FormMain : Form
    {
        FormMainExt frmMainExt;

        bool bRus { get { return ddlType.SelectedIndex == 0; } }

        public FormMain()
        {
            InitializeComponent();
            ddlType.SelectedIndex = 0;
            
        }

        private void FormMain_Shown(object sender, EventArgs e)
        {
            frmMainExt = new FormMainExt(this);
        }

        // поддерживается # b m 5 7 9. Максимальный аккорд G#m7
        Note[] StringToNotes(string str)
        {
            List<Note> ret = new List<Note>();

            string[] sl = str.Split(' ');
            for (int i = 0; i < sl.Length; i++)
            {
                Note nt = null;
                string s = sl[i].Trim();
                if (s == "") continue;
                if (s.Length > 4) { throw new Exception("Неизвестный аккорд " + s); }
                else
                {
                    int n = -1;
                    // смотрим ноту
                    switch (s[0])
                    {
                        case 'C': n = 0; break;
                        case 'D': n = 2; break;
                        case 'E': n = 4; break;
                        case 'F': n = 5; break;
                        case 'G': n = 7; break;
                        case 'A': n = 9; break;
                        case 'B': if (bRus) n = 10; else n = 11; break;
                        case 'H': if (bRus) n = 11; break;
                    }
                    if (n == -1) throw new Exception("Неизвестный аккорд " + s);

                    // ищем диез или бемоль
                    bool bFind = false;
                    for (int j = 1; j < s.Length; j++)
                    {
                        if (s[j] == '#')
                        {
                            if (bFind) throw new Exception("В аккорде " + s + " невозможно определить тональность");
                            // если нота С или B-рус или H
                            if (n == 4 || n == 10 || n == 11) throw new Exception("В аккорде " + s + " не может быть #");
                           
                            bFind = true;
                            n++;
                        }

                        if (s[j] == 'b')
                        {
                            if (bFind) throw new Exception("В аккорде " + s + " невозможно определить тональность");
                            // если нота С или B-рус или F
                            if (n == 0 || n == 5 || n == 10) throw new Exception("В аккорде " + s + " не может быть b");
                            bFind = true;
                            n--;
                        }
                    }
                    nt = new Note(n);

                    // ищем минор
                    bFind = false;
                    for (int j = 1; j < s.Length; j++)
                        if (s[j] == 'm')
                        {
                            if (bFind) throw new Exception("В аккорде " + s + " более 1 раза повторяется 'm'");
                            bFind = true;
                            nt.Minor = true;
                        }

                    // ищем номер
                    bFind = false;
                    for (int j = 1; j < s.Length; j++)
                    {
                        int nm = 0;
                        if (int.TryParse(s[j].ToString(), out nm))
                        {
                            if (bFind) throw new Exception("В аккорде " + s + " более 1 раза повторяется номер");
                            bFind = true;
                            nt.Nm = nm;
                        }
                    }

                    string ss = s.Substring(1,s.Length-1).Replace("#", "").Replace("b", "").Replace("m", "").Replace("5", "");
                    if (nt.Nm != 5) ss = ss.Replace(nt.Nm.ToString(), "");
                    if (ss != "") throw new Exception("В аккорде " + s + " есть неизвестные символы");


                }
                ret.Add(nt);
            }
            return ret.ToArray();
        }

        string NotesToString(Note[] nt)
        {
            Note.bRus = bRus;
            string ret = "";
            for (int i = 0; i < nt.Length; i++)
            {
                if (i > 0) ret += " ";
                ret += nt[i].ToString();
            }
            return ret;
        }

        private void trTone_Scroll(object sender, EventArgs e)
        {
            lblTone.Text = (trTone.Value - 11).ToString();
            TranparentAccords();
        }

        bool bMinorDown = false;
        private void btn_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
        {
            if (e.KeyValue == 17 || e.KeyValue == 16)
            {
                if (e.KeyValue == 17) { bMinorDown = true; lblMinor.Visible = true; }
            }
        }

        private void btn_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyValue == 17) { bMinorDown = false; lblMinor.Visible = false; }
        }

        private void lBtnHelp_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            FormMiniHelp frmMiniHelp = new FormMiniHelp();
            frmMiniHelp.ShowDialog();
            frmMiniHelp.Dispose();
            frmMiniHelp = null;
        }

        private void lBtnMore_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            //
        }

        private void txbAcc_TextChanged(object sender, EventArgs e)
        {
             TranparentAccords();
        }

        Color clrErr = Color.FromArgb(255, 200, 170);

        void TranparentAccords()
        {
            txbRes.Text = "";
            lblErr.Visible = false;
            txbAcc.BackColor = Color.White;
            try
            {
                Note[] nt = StringToNotes(txbAcc.Text.Trim());
                int sh = Convert.ToInt32(lblTone.Text);
                bool bErr = false;
                for (int i = 0; i < nt.Length; i++)
                {
                    nt[i].Acc += sh;
                    if (nt[i].Acc < 0) nt[i].Acc += 12; if (nt[i].Acc > 11) nt[i].Acc -= 12;
                }
                if (!bErr) txbRes.Text = NotesToString(nt);
            }
            catch (Exception ex) { txbAcc.BackColor = clrErr; lblErr.Text = "Ошибка транспонирования: " + ex.Message; lblErr.Visible = true; } 
        }

        private void btnAcc_Click(object sender, EventArgs e)
        {
            txbAcc.Text = txbAcc.Text.Trim();
            if (txbAcc.Text != "") txbAcc.Text += " ";
            string s = (bMinorDown ? "m" : "");
            if (sender == btnC) txbAcc.Text += "C" + s;
            if (sender == btnCd) txbAcc.Text += "C#" + s;
            if (sender == btnD) txbAcc.Text += "D" + s;
            if (sender == btnDd) txbAcc.Text += "D#" + s;
            if (sender == btnE) txbAcc.Text += "E" + s;
            if (sender == btnF) txbAcc.Text += "F" + s;
            if (sender == btnFd) txbAcc.Text += "F#" + s;
            if (sender == btnG) txbAcc.Text += "G" + s;
            if (sender == btnGd) txbAcc.Text += "G#" + s;
            if (sender == btnA) txbAcc.Text += "A" + s;
            if (sender == btnAd) txbAcc.Text += "B" + s;
            if (sender == btnH) txbAcc.Text += "H" + s;
        }

        private void tBtnExtVer_Click(object sender, EventArgs e)
        {
            frmMainExt.Location = Location;
            frmMainExt.Show();
            Hide();
        }

        private void ddlType_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (bRus)
            {
                btnAd.Text = "B";
                btnH.Text = "H";
            }
            else
            {
                btnAd.Text = "A#";
                btnH.Text = "B";
            }
            TranparentAccords();
        }

        private void tBtnHelp_Click(object sender, EventArgs e)
        {
            FormMiniHelp frm = new FormMiniHelp();
            frm.ShowDialog();
            frm.Dispose();
        }

        private void tBtnClear_Click(object sender, EventArgs e)
        {
            txbAcc.Text = "";
            trTone.Value = 11;
            lblTone.Text = "0";
        }

    }
}
